package com.yanqu.road.server.manager.strongholdwar;

import com.yanqu.road.entity.activity.stronghold.*;
import com.yanqu.road.entity.activity.stronghold.config.StrongholdNpcConfig;
import com.yanqu.road.entity.activity.stronghold.config.StrongholdWildConfig;
import com.yanqu.road.entity.log.cross.stronghold.LogStrongholdBox;
import com.yanqu.road.entity.log.cross.stronghold.LogStrongholdEvent;
import com.yanqu.road.entity.log.cross.stronghold.LogStrongholdNpc;
import com.yanqu.road.entity.log.cross.stronghold.LogStrongholdPvp;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.config.goods.OpenGoodsBagResult;
import com.yanqu.road.entity.enums.activity.stronghold.eStrongholdEventType;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.player.UserPatrons;
import com.yanqu.road.logic.bussiness.player.activity.UserStrongholdBusiness;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.server.manager.log.CrossAutoLogMgr;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.pb.activity.StrongholdWarProto;
import com.yanqu.road.pb.player.PlayerProto;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manger.TempCommonMgr;
import com.yanqu.road.server.manger.TempGoodsBagMgr;
import com.yanqu.road.server.pb.CrossStrongholdPb;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigInteger;
import java.util.*;

public class StrongholdWildModel {

    private final static Logger LOGGER = LogManager.getLogger(StrongholdWildModel.class);

    private int activityId;
    private int wildId;
    private long lastFightTime;
    private StrongholdActivityModel activityModel;
    private List<StrongholdWildUserData> wildUserDataList;

    private final Object WILD_LOCK = new Object();
    private final Object ADD_BOX_LOCK = new Object();

    private StrongholdHouseData houseData;
    private RandomHelper randomHelper = new RandomHelper();

    public StrongholdWildModel(StrongholdActivityModel activityModel, int activityId, int wildId, StrongholdHouseData houseData, List<StrongholdWildUserData> houseUserList) {
        this.wildId = wildId;
        wildUserDataList = houseUserList;
        if (houseData == null) {
            houseData = new StrongholdHouseData();
            houseData.setGroupId(activityModel.getGroupId());
            houseData.setHouseId(this.wildId);
            houseData.setActivityId(activityId);
            houseData.setInsertOption();
        }
        this.houseData = houseData;
        this.activityId = activityId;
        this.activityModel = activityModel;
    }


    public int getStatus() {
        if (System.currentTimeMillis() - lastFightTime <= 60 * 1000) {
            for (StrongholdWildUserData data : new ArrayList<>(wildUserDataList)) {
                if (data.getRewardPoints() >= 500) {
                    return 2;
                }
            }
            return 1;
        }
        return 0;
    }

    public StrongholdWildUserData findWildUser(long serverId, long userId) {
        List<StrongholdWildUserData> tempList = new ArrayList<>(wildUserDataList);
        for (StrongholdWildUserData wildPatrons : tempList) {
            if (serverId == wildPatrons.getUserBaseInfo().getServerId() && userId == wildPatrons.getUserId()) {
                return wildPatrons;
            }
        }
        return null;
    }

    /**
     * 添加宝箱
     */
    public StrongholdWildBox addBox(int itemId) {
        int nextBoxId = activityModel.getNextBoxId();
        StrongholdWildBox box = new StrongholdWildBox(nextBoxId, itemId);
        box.setGroupId(activityModel.getGroupId());
        box.setActivityId(activityId);
        box.setWildId(wildId);
        box.setInsertOption();
        return box;
    }

    /**
     * 拾取宝箱
     *
     * @param boxId
     * @param eventId
     */
    public int pickUpBox(StrongholdWildUserData wildUserData, int boxId, int eventId) {
        StrongholdWildBox box = activityModel.getBox(boxId);
        if (box == null) {
            wildUserData.resetEventEmpty();
            return GameErrorCode.E_STRONGHOLD_BOX_PICK_UP_ALREADY;
        }
        if (box.getServerId() > 0 || box.getUserId() > 0) {
            //已经被别人捡走
            wildUserData.resetEventEmpty();
            return GameErrorCode.E_STRONGHOLD_BOX_PICK_UP_ALREADY;
        }
        if (wildUserData == null || wildUserData.getPatrons().getCurrentBlood().compareTo(BigInteger.ZERO) <= 0) {
            //未派遣门客 或者门客被击败
            return GameErrorCode.E_STRONGHOLD_PATRONS_BEEN_KILLED;
        }
        if (activityModel.getUserBoxSize(wildUserData.getBoxList()) >= CrossStrongholdActivityMgr.maxBoxNum(activityId)) {
            //宝箱没有位置
            return GameErrorCode.E_STRONGHOLD_BOX_FULL;
        }
        wildUserData.resetEventEmpty();
        addBoxToUser(wildUserData, box);
        CrossAutoLogMgr.add(new LogStrongholdBox(
                activityId,
                box.getUserId(),
                eventId,
                box.getType(),
                box.getBoxId(),
                0,
                0,
                CrossStrongholdActivityMgr.getWildName(activityId, wildId)
        ));
        return 0;
    }

    private void addBoxToUser(StrongholdWildUserData wildUserData, StrongholdWildBox box) {
        box.setUserId(wildUserData.getUserId());
        box.setServerId(wildUserData.getServerId());
        box.setPickUpTime(System.currentTimeMillis() / 1000);
        int index = wildUserData.addBox(box.getBoxId());
    }


    /**
     * 将门客从当前据点移出
     *
     * @param serverId
     * @param userId
     */
    public void goOut(long serverId, long userId) {
        synchronized (WILD_LOCK) {
            synchronized (wildUserDataList) {
                Iterator<StrongholdWildUserData> iterator = wildUserDataList.iterator();
                while (iterator.hasNext()) {
                    StrongholdWildUserData patrons = iterator.next();
                    if (patrons.getUserBaseInfo().getServerId() == serverId && userId == patrons.getUserId()) {
                        patrons.resetEventEmpty();
                        patrons.setWildId(0);
                        iterator.remove();
                        break;
                    }
                }
            }
        }
    }

    public StrongwildBattleResult attackEnemy(int eventId, StrongholdWildUserData attackPatrons, StrongholdWildUserData defendUser) {
        boolean attackWin = false;
        int attackPoints = 0;
        int defendPoints = 0;
        String damage;
        if (attackPatrons.getPatrons().getCurrentBlood().compareTo(defendUser.getPatrons().getCurrentBlood()) >= 0) {
            attackWin = true;
            damage = defendUser.getPatrons().getCurrentBlood().toString();
            attackPatrons.setRewardPoints(attackPatrons.getRewardPoints() + CrossStrongholdActivityMgr.getKillPoints(activityId));
            attackPoints = defendUser.getRewardPoints();
            defendUser.setRewardPoints(0);
        } else {
            damage = attackPatrons.getPatrons().getCurrentBlood().toString();
            defendUser.getPatrons().setCurrentBlood(defendUser.getPatrons().getCurrentBlood().subtract(attackPatrons.getPatrons().getCurrentBlood()));
            attackPatrons.getPatrons().setCurrentBlood(BigInteger.ZERO);
            defendUser.addDefendInfo(attackPatrons.getUserId());
            int defendTimes = defendUser.getDefendTimes(attackPatrons.getUserId());
            String param = CrossStrongholdActivityMgr.getDenfendPointsParam(activityId);
            String[] arr = param.split(";");
            int points = Math.max(Integer.parseInt(arr[0]) - (defendTimes - 1) * Integer.parseInt(arr[1]), Integer.parseInt(arr[2]));
            defendUser.setRewardPoints(defendUser.getRewardPoints() + points);
            attackPatrons.setRewardPoints(0);
            defendPoints = points;
        }
        StrongwildBattleResult battleResult;
        int attackRewardPoints = 0;
        int defenderRewardPoints = 0;
        if (attackWin) {
            battleResult = updatePatrons(eventId, attackPatrons, defendUser);
            attackRewardPoints = attackPoints;
        } else {
            battleResult = updatePatrons(eventId, defendUser, attackPatrons);
            //失败也获得积分
            attackRewardPoints = CrossStrongholdActivityMgr.getLosePoints(activityId);
            defenderRewardPoints = defendPoints;
        }
        battleResult.setDamage(damage);
        battleResult.setKill(attackWin);
        //通知进攻 生成战报
        noticeEnemy(attackPatrons, attackWin, defendUser, battleResult, 1, attackRewardPoints);
        //通知防守 生成战报
        noticeEnemy(defendUser, !attackWin, attackPatrons, battleResult, 2, defenderRewardPoints);
        if (attackWin) {
            attackPatrons.resetEventEmpty();
        }
        return battleResult;
    }

    private void addPvpBoxLog(long userId, int eventId, StrongholdWildBox box, int isGet) {
        CrossAutoLogMgr.add(new LogStrongholdBox(
                activityId,
                userId,
                eventId,
                box.getType(),
                box.getBoxId(),
                isGet,
                1,
                CrossStrongholdActivityMgr.getWildName(activityId, wildId)
        ));
    }

    private void noticeEnemy(StrongholdWildUserData userData, boolean isWin, StrongholdWildUserData enemyUser, StrongwildBattleResult battleResult, int type, int rewardPoints) {
        try {
            StrongholdWarProto.CrossStrongholdBeenAttackedMsg.Builder syncMsg = StrongholdWarProto.CrossStrongholdBeenAttackedMsg.newBuilder();
            long serverId = userData.getServerId();
            syncMsg.setUserId(userData.getUserId());
            syncMsg.setWin(isWin);
            syncMsg.setActivityId(activityId);
            syncMsg.setRewardPoints(rewardPoints);
            syncMsg.setEnemyUserId(enemyUser.getUserId());
            if (isWin) {
                for (StrongholdWildBox box : battleResult.getWinBoxList()) {
                    syncMsg.addBox(box.getType());
                }
            } else {
                syncMsg.addAllBox(battleResult.getLostBoxList());
            }
            syncMsg.setType(type);
            UserBaseInfo enemyUserUserBaseInfo = enemyUser.getUserBaseInfo();
            PlayerProto.PlayerBaseTempMsg.Builder baseTempMsg = PlayerBasePb.parsePlayerBaseTempMsg(enemyUserUserBaseInfo);
            syncMsg.setEnemyInfo(baseTempMsg);
            StrongholdWarProto.StrongholdDispatchPatronsTempMsg.Builder patronsMsg = CrossStrongholdPb.getWildUserMsg(userData);
            syncMsg.setDispatchPatrons(patronsMsg);
            YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(GameProtocol.S_CROSS_STRONGHOLD_WILD_BEEN_ATTACKED, syncMsg);
            MessageHelper.sendPacket(serverId, userData.getUserId(), pbMsg);
        } catch (Exception e) {
            LOGGER.error("notice enemy msg error. ", e);
        }
    }


    /**
     * 更新对战双方的数据
     */
    private StrongwildBattleResult updatePatrons(int eventId, StrongholdWildUserData winPatrons, StrongholdWildUserData losePatrons) {
        StrongwildBattleResult result = new StrongwildBattleResult();
        winPatrons.getPatrons().setCurrentBlood(winPatrons.getPatrons().getCurrentBlood().subtract(losePatrons.getPatrons().getCurrentBlood()));
        if (winPatrons.getPatrons().getCurrentBlood().compareTo(BigInteger.ONE) < 0) {
            //最少保留一点
            winPatrons.getPatrons().setCurrentBlood(BigInteger.ONE);
        }
        losePatrons.resetDefenInfo();
        losePatrons.getPatrons().setCurrentBlood(BigInteger.ZERO);
        List<Integer> boxList = losePatrons.getBoxList();
        List<Integer> lostBoxList = new ArrayList<>();
        List<StrongholdWildBox> winBoxList = new ArrayList<>();
        if (boxList != null) {
            Iterator<Integer> iterator = boxList.iterator();
            while (iterator.hasNext()) {
                Integer boxId = iterator.next();
                StrongholdWildBox box = activityModel.getBox(boxId);
                if (box != null && !CrossStrongholdActivityMgr.canOpenBox(activityId, box.getType(), box.getPickUpTime())) {
                    iterator.remove();
                    lostBoxList.add((box.getType()));
                    addPvpBoxLog(losePatrons.getUserId(), eventId, box, 1);
                    if (activityModel.getUserBoxSize(winPatrons.getBoxList()) < 4) {
                        result.addRobBox(boxId + ";" + box.getType());
                        //重置时间
                        addBoxToUser(winPatrons, box);
                        winBoxList.add(box);
                        addPvpBoxLog(winPatrons.getUserId(), eventId, box, 0);
                    } else {
                        // 放回宝箱池中
                        returnBoxToPool(box);
                        result.addReturnBox(boxId + ";" + box.getType());
                    }
                }
            }
            losePatrons.setUpdateOption();
        }
        result.setLostBoxList(lostBoxList);
        result.setWinBoxList(winBoxList);
        return result;
    }

    private void returnBoxToPool(StrongholdWildBox box) {
        box.setServerId(0);
        box.setUserId(0);
        box.setWildId(wildId);
        box.setBeSearched(false);
    }

    /**
     * 用户进来
     *
     * @param wildPatrons
     */
    public void userEnter(StrongholdWildUserData wildPatrons) {
        synchronized (wildUserDataList) {
            wildPatrons.setWildId(wildId);
            wildUserDataList.add(wildPatrons);
        }
        //通知在该据点的玩家
        for (StrongholdWildUserData userData : wildUserDataList) {

        }
    }

    /**
     * 搜索
     *
     * @param serverId
     * @param userId
     */
    public StrongholdWarProto.CrossStrongholdSearchRespMsg.Builder search(long serverId, long userId) {
        StrongholdWarProto.CrossStrongholdSearchRespMsg.Builder resp = StrongholdWarProto.CrossStrongholdSearchRespMsg.newBuilder();
        synchronized (WILD_LOCK) {

            StrongholdWildUserData userData = findWildUser(serverId, userId);
            if (userData == null || userData.getPatrons().getCurrentBlood().compareTo(BigInteger.ZERO) <= 0) {
                resp.setRet(GameErrorCode.E_STRONGHOLD_PATRONS_BEEN_KILLED);
                return resp;
            }
            if (userData.getEventData() != null) {
                resp.setRet(GameErrorCode.E_STRONGHOLD_EVENT_NOT_DEAL);
                return resp;
            }
            //判断是否有其他联盟的玩家
            List<Integer> hasEventList = new ArrayList<>();
            hasEventList.add(1);
            List<StrongholdWildUserData> otherUnionUserList = findOtherUnionUser(userData);
            if (otherUnionUserList.size() > 0) {
                hasEventList.add(2);
            }

            //判断是否还有宝箱
            List<StrongholdWildBox> lastBoxList = getLastBox();
            if (lastBoxList.size() > 0) {
                hasEventList.add(0);
            }


            // 随出事件
            //随机一个事件
            StrongholdWildConfig houseInfo = CrossStrongholdActivityMgr.getHouseInfo(activityId, wildId);
            int totalWeight = 0;
            Map<Integer, Integer> eventWeightMap = new HashMap<>();
            String eventWeight = houseInfo.getEventWeight();
            String[] split = eventWeight.split(";");
            if (houseInfo.getId() == wildId) {
                for (Integer id : hasEventList) {
                    int weight = Integer.parseInt(split[id]);
                    totalWeight += weight;
                    eventWeightMap.put(id, weight);
                }
            }
            int randomNum = randomHelper.next(0, totalWeight);
            int eventType = 1;
            for (Map.Entry<Integer, Integer> entry : eventWeightMap.entrySet()) {
                Integer value = entry.getValue();
                if (randomNum < value) {
                    eventType = entry.getKey();
                    break;
                }
                randomNum -= value;
            }
            int eventId = activityModel.nextEventId();
            int boxType = -1;
            if (eventType == eStrongholdEventType.BOX.getValue()) {
                //宝箱
                StrongholdWildBox box = randomSearchBox(lastBoxList);
                StrongholdBoxEvent boxEvent = new StrongholdBoxEvent();
                boxEvent.setEventId(eventId);
                boxEvent.setBoxId(box.getBoxId());
                boxEvent.setBoxType(box.getType());
                int houseType = houseInfo.getType();
                int itemId = CrossStrongholdActivityMgr.getHouseItem(activityId, houseType);
                GoodsInfo goodsInfo = TempCommonMgr.getGoodsInfo(CrossStrongholdActivityMgr.getBoxItemId(activityId, box.getType()));
                List<BigInteger> paramList = goodsInfo.getParamList();
                Property property = new Property(itemId, paramList.get(2));
                property.addProperty(CrossStrongholdActivityMgr.getRewardPointsId(activityId), paramList.get(1));
                box.setReward(PropertyHelper.parsePropertyToString(property));
                boxEvent.setReward(box.getReward());
                boxEvent.setPoints(goodsInfo.getParamList().get(1).intValue());
                userData.setEventData(boxEvent);
                boxType = box.getType();
            } else if (eventType == eStrongholdEventType.PATRONS.getValue()) {
                //门客
                StrongholdWildUserData enemyUser = matchOtherUser(serverId, otherUnionUserList);
                UserPatrons patrons = enemyUser.getPatrons();
                int curBlood = CrossStrongholdActivityMgr.calcCurBlood(patrons.getCurrentBlood(), patrons.getTotalBlood());
                StrongholdPatronsEvent patronsEvent = new StrongholdPatronsEvent();
                patronsEvent.setEventId(eventId);
                patronsEvent.setBlood(curBlood);
                patronsEvent.setType(eventType);
                patronsEvent.setRewardPoints(enemyUser.getRewardPoints());
                List<Integer> boxList = getCanRobBoxList(enemyUser);
                patronsEvent.setBoxList(boxList);
                patronsEvent.setUserBaseInfo(enemyUser.getUserBaseInfo());
                patronsEvent.setPatrons(enemyUser.getPatrons());
                patronsEvent.setLosePoints(CrossStrongholdActivityMgr.getLosePoints(activityId));
                int houseItem = CrossStrongholdActivityMgr.getHouseItem(activityId, houseInfo.getType());
                patronsEvent.setWinReward(PropertyHelper.parsePropertyToString(new Property(houseItem, BigInteger.valueOf(CrossStrongholdActivityMgr.getWildWinReward(activityId)))));
                patronsEvent.setLoseReward(PropertyHelper.parsePropertyToString(new Property(houseItem, BigInteger.valueOf(CrossStrongholdActivityMgr.getWildLoseReward(activityId)))));
                userData.setEventData(patronsEvent);
            } else {
                //NPC事件
                List<StrongholdNpcConfig> npcConfigList = CrossStrongholdActivityMgr.getAllNpcConfig(activityId);
                StrongholdNpcConfig npcConfig = npcConfigList.get(randomHelper.next(0, npcConfigList.size()));
                StrongholdNpcEvent npcEvent = new StrongholdNpcEvent();
                npcEvent.setEventId(eventId);
                npcEvent.setType(eventType);
                npcEvent.setNpcId(npcConfig.getId());
                userData.setEventData(npcEvent);
            }
            CrossAutoLogMgr.add(new LogStrongholdEvent(
                    activityId,
                    activityModel.getGroupId(),
                    userId,
                    eventId,
                    CrossStrongholdActivityMgr.getWildName(activityId, wildId),
                    eventType,
                    boxType,
                    false
            ));

            StrongholdWarProto.StrongholdEventTempMsg.Builder eventMsg = CrossStrongholdPb.getEventMsg(activityId, userData.getEventData());
            resp.setRet(0);
            resp.setEvent(eventMsg);
            return resp;
        }
    }

    private StrongholdWildUserData matchOtherUser(long serverId, List<StrongholdWildUserData> otherUnionUserList) {
        List<StrongholdWildUserData> otherServerUserList = new ArrayList<>();
        List<StrongholdWildUserData> sameServerUserList = new ArrayList<>();
        for (StrongholdWildUserData data : otherUnionUserList) {
            if (data.getServerId() != serverId) {
                otherServerUserList.add(data);
            }else {
                sameServerUserList.add(data);
            }
        }
        if (!otherServerUserList.isEmpty()) {
            return otherServerUserList.get(randomHelper.next(0, otherServerUserList.size()));
        }
        return sameServerUserList.get(randomHelper.next(0, sameServerUserList.size()));
    }

    /**
     * 从剩余的宝箱列表中随一个， 优先随未被搜索到的
     *
     * @param lastBoxList
     * @return
     */
    private StrongholdWildBox randomSearchBox(List<StrongholdWildBox> lastBoxList) {
        List<StrongholdWildBox> unSearchList = new ArrayList<>();
        for (StrongholdWildBox box : lastBoxList) {
            if (!box.isBeSearched()) {
                unSearchList.add(box);
            }
        }
        StrongholdWildBox box;
        if (unSearchList.size() > 0) {
            box = unSearchList.get(randomHelper.next(0, unSearchList.size()));
        } else {
            box = lastBoxList.get(randomHelper.next(0, lastBoxList.size()));
        }
        box.setBeSearched(true);
        return box;


    }

    private List<Integer> getCanRobBoxList(StrongholdWildUserData enemyUser) {
        List<Integer> boxList = new ArrayList<>();
        for (Integer boxId : enemyUser.getBoxList()) {
            StrongholdWildBox box = activityModel.getBox(boxId);
            if (box != null && !CrossStrongholdActivityMgr.canOpenBox(activityId, box.getType(), box.getPickUpTime())) {
                boxList.add(box.getType());
            }
        }
        return boxList;
    }

    /**
     * 找出其他联盟玩家
     */
    private List<StrongholdWildUserData> findOtherUnionUser(StrongholdWildUserData userData) {
        List<StrongholdWildUserData> list = new ArrayList<>();
        long serverId = userData.getServerId();
        String unionUid = userData.getUserBaseInfo().getUnionUid();
        for (StrongholdWildUserData wildUserData : new ArrayList<>(wildUserDataList)) {
            if (!Objects.equals(unionUid, wildUserData.getUserBaseInfo().getUnionUid())) {
                //区服id不同 或者 联盟id不同 ，则认为是其他联盟的玩家
                if (wildUserData.getPatrons().getCurrentBlood().compareTo(BigInteger.ZERO) > 0) {
                    list.add(wildUserData);
                }
            }
        }
        return list;
    }

    /**
     * 处理事件
     *
     * @param serverId
     * @param userId
     * @param isDeal
     */
    public StrongholdWarProto.CrossDealStrongholdEventResp.Builder dealEvent(long serverId, long userId, boolean isDeal) {
        synchronized (WILD_LOCK) {
            StrongholdWarProto.CrossDealStrongholdEventResp.Builder resp = StrongholdWarProto.CrossDealStrongholdEventResp.newBuilder();
            resp.setRet(0);
            resp.setDeal(isDeal);
            StrongholdWildUserData wildUserData = findWildUser(serverId, userId);
            StrongholdBaseEvent event = wildUserData.getEventData();
            if (event == null) {
                resp.setRet(GameErrorCode.E_STRONGHOLD_EVENT_NOT_FOUND);
                return resp;
            }

            if (!isDeal) {
                //清空事件即可
                wildUserData.setEventData(null);
                return resp;
            }
            int type = event.getType();
            resp.setDealEventType(type);
            StrongholdWarProto.StrongholdEventResultMsg.Builder resultMsg = StrongholdWarProto.StrongholdEventResultMsg.newBuilder();
            resultMsg.setType(type);
            int boxType = -1;
            if (type == 1) {
                //NPC
                StrongholdNpcEvent npcEvent = (StrongholdNpcEvent) event;
                int npcId = npcEvent.getNpcId();
                StrongholdNpcConfig npcConfig = CrossStrongholdActivityMgr.getNpcConfig(activityId, npcId);
                //返回奖励
                wildUserData.setEventData(null);
                String[] arr = npcConfig.getRewards().split(";");
                int rewardPoints = Integer.parseInt(arr[0]);
                int itemNum = Integer.parseInt(arr[1]);
                Property property = new Property();
                property.addProperty(CrossStrongholdActivityMgr.getRewardPointsId(activityId), BigInteger.valueOf(rewardPoints));
                StrongholdWildConfig houseInfo = CrossStrongholdActivityMgr.getHouseInfo(activityId, wildId);
                int houseItem = CrossStrongholdActivityMgr.getHouseItem(activityId, houseInfo.getType());
                property.addProperty(houseItem, BigInteger.valueOf(itemNum));
                String rewardStr = PropertyHelper.parsePropertyToString(property);
                resultMsg.setReward(rewardStr);
                // 加个日志
                CrossAutoLogMgr.add(new LogStrongholdNpc(
                        activityId,
                        userId,
                        npcEvent.getEventId(),
                        CrossStrongholdActivityMgr.getWildName(activityId, wildId),
                        npcConfig.getNeedMoney(),
                        rewardStr
                ));
            } else if (type == 0) {
                //宝箱
                StrongholdBoxEvent boxEvent = (StrongholdBoxEvent) event;
                boxType = boxEvent.getBoxType();
                int ret = pickUpBox(wildUserData, boxEvent.getBoxId(), boxEvent.getEventId());
                if (ret != 0) {
                    resp.setRet(ret);
                    return resp;
                }
            } else if (type == 2) {
                //门客
                StrongholdPatronsEvent patronsEvent = (StrongholdPatronsEvent) event;
                long enemyServerId = patronsEvent.getUserBaseInfo().getServerId();
                long enemyUserId = patronsEvent.getPatrons().getUserId();
                StrongholdWildUserData enemyUser = findWildUser(enemyServerId, enemyUserId);
                if (enemyUser == null) {
                    //门客已经跑了
                    wildUserData.resetEventEmpty();
                    resp.setRet(GameErrorCode.E_STRONGHOLD_ENEMY_NOT_IN_SAME_WAILD);
                    return resp;
                }
                if (patronsEvent.getPatrons().getPatronsId() != enemyUser.getPatrons().getPatronsId()) {
                    wildUserData.resetEventEmpty();
                    resp.setRet(GameErrorCode.E_STRONGHOLD_ENEMY_BEEN_KILLED);
                    return resp;
                }
                if (enemyUser.getPatrons().getCurrentBlood().compareTo(BigInteger.ZERO) <= 0) {
                    //对方已经被击败
                    wildUserData.resetEventEmpty();
                    resp.setRet(GameErrorCode.E_STRONGHOLD_ENEMY_BEEN_KILLED);
                    return resp;
                }
                int rewardPoints = enemyUser.getRewardPoints();
                StrongwildBattleResult battleResult = attackEnemy(event.getEventId(), wildUserData, enemyUser);
                resp.setPatronsId(wildUserData.getPatrons().getPatronsId());
                lastFightTime = System.currentTimeMillis();
                Property property = new Property();
                if (enemyUser.getPatrons().getCurrentBlood().compareTo(BigInteger.ZERO) > 0) {
                    //如果对方还活着 更新事件血量
                    patronsEvent.setBlood(CrossStrongholdActivityMgr.calcCurBlood(enemyUser.getPatrons().getCurrentBlood(), enemyUser.getPatrons().getTotalBlood()));
                    patronsEvent.setRewardPoints(enemyUser.getRewardPoints());
                    patronsEvent.setBoxList(getCanRobBoxList(enemyUser));
                    rewardPoints = CrossStrongholdActivityMgr.getLosePoints(activityId);
                    property.addProperty(PropertyHelper.parseStringToProperty(patronsEvent.getLoseReward()));
                } else {
                    property.addProperty(PropertyHelper.parseStringToProperty(patronsEvent.getWinReward()));
                    for (StrongholdWildBox box : battleResult.getWinBoxList()) {
                        resultMsg.addWinBox(CrossStrongholdPb.getBoxMsg(box));
                    }
                }
                //增加积分
                property.addProperty(CrossStrongholdActivityMgr.getRewardPointsId(activityId), BigInteger.valueOf(rewardPoints));
                resultMsg.setReward(PropertyHelper.parsePropertyToString(property));
                CrossAutoLogMgr.add(new LogStrongholdPvp(
                        userId,
                        activityId,
                        event.getEventId(),
                        CrossStrongholdActivityMgr.getWildName(activityId, wildId),
                        wildUserData.getPatrons().getPatronsId(),
                        battleResult.getDamage(),
                        battleResult.isKill(),
                        enemyUserId,
                        enemyUser.getPatrons().getCurrentBlood().toString(),
                        battleResult.getRobBoxList(),
                        battleResult.getReturnBoxList(),
                        rewardPoints
                ));
            }
            StrongholdBaseEvent eventData = wildUserData.getEventData();
            if (eventData != null) {
                StrongholdWarProto.StrongholdEventTempMsg.Builder eventMsg = CrossStrongholdPb.getEventMsg(activityId, eventData);
                resp.setEvent(eventMsg);
            }

            resultMsg.setPatrons(CrossStrongholdPb.getWildUserMsg(wildUserData));
            resp.setResult(resultMsg);

            // 加个事件日志
            CrossAutoLogMgr.add(new LogStrongholdEvent(
                    activityId,
                    activityModel.getGroupId(),
                    userId,
                    event.getEventId(),
                    CrossStrongholdActivityMgr.getWildName(activityId, wildId),
                    event.getType(),
                    boxType,
                    true
            ));
            return resp;
        }
    }


    public void checkAndRefreshBox() {
        List<Integer> refreshTimeList = CrossStrongholdActivityMgr.getBoxRefreshTime(activityId);
        if (refreshTimeList.isEmpty()) {
            return;
        }
        synchronized (ADD_BOX_LOCK) {
            long refreshBoxTime = houseData.getRefreshBoxTime();
            StrongholdWildConfig houseInfo = CrossStrongholdActivityMgr.getHouseInfo(activityId, wildId);
            int curTime = CrossStrongholdActivityMgr.getCurTime(activityId) * 60;
            for (int i = 0; i < refreshTimeList.size(); i++) {
                Integer freshTime = refreshTimeList.get(i);
                if (refreshBoxTime < freshTime && curTime >= freshTime) {
                    // 已经刷新时间小于配置时间， 且当前时间已经大于配置时间
                    houseData.setRefreshBoxTime(freshTime);
                    List<StrongholdWildBox> addBoxList = new ArrayList<>();
                    //增加宝箱
                    List<Integer> targetNumList = houseInfo.getAddBoxMap().get(i);
                    List<Integer> boxIdList = CrossStrongholdActivityMgr.getBoxIdList(activityId);
                    for (int j = 0; j < boxIdList.size(); j++) {
                        Integer targetNum = targetNumList.get(j);
                        addBox(addBoxList, targetNum, j);
                    }
                    activityModel.refreshAddBox(addBoxList);
                }
            }
        }
    }

    private void addBox(List<StrongholdWildBox> addBoxList, Integer targetNum, int type) {
        int num = Math.max(targetNum - getCurBoxNumByType(type), 0);
        for (int j = 0; j < num; j++) {
            addBoxList.add(addBox(type));
        }
    }

    private int getCurBoxNumByType(int type) {
        int num = 0;
        for (StrongholdWildBox box : activityModel.getBoxByWildId(wildId)) {
            if (box.getUserId() == 0 && box.getType() == type) {
                num++;
            }
        }
        return num;
    }

    public void save() {
        if (houseData != null) {
            if (houseData.isInsertOption()) {
                UserStrongholdBusiness.addHouseData(houseData);
            } else if (houseData.isUpdateOption()) {
                UserStrongholdBusiness.updateHouseData(houseData);
            }
        }
    }

    /**
     * 获取据点状态
     *
     * @return
     */
    public StrongholdWarProto.StrongholdFightStatusTempMsg.Builder getStatusMsg() {
        StrongholdWarProto.StrongholdFightStatusTempMsg.Builder msg = StrongholdWarProto.StrongholdFightStatusTempMsg.newBuilder();
        msg.setId(wildId);
        msg.setStatus(getStatus());
        return msg;
    }

    /**
     * 获取据点信息
     *
     * @param userData
     * @return
     */
    public StrongholdWarProto.StrongholdDataResp.Builder getWildData(StrongholdWildUserData userData) {
        StrongholdWarProto.StrongholdDataResp.Builder msg = StrongholdWarProto.StrongholdDataResp.newBuilder();
        StrongholdWarProto.StrongholdDataTempMsg.Builder wildMsg = StrongholdWarProto.StrongholdDataTempMsg.newBuilder();
        wildMsg.setTotalPlayerNum(getWildUserNum());
        wildMsg.setUnionMemberNum(findSameUnionNum(userData));
        wildMsg.addAllMemberName(findSameUnionMemberName(userData));
        wildMsg.setBoxNum(getLastBoxNum());
        msg.setStrongholdData(wildMsg);
        List<StrongholdWildBox> boxList = activityModel.getBoxList(userData.getBoxList());
        for (StrongholdWildBox box : boxList) {
            msg.addBox(CrossStrongholdPb.getBoxMsg(box));
        }
        StrongholdBaseEvent eventData = userData.getEventData();
        if (eventData != null) {
            StrongholdWarProto.StrongholdEventTempMsg.Builder eventMsg = CrossStrongholdPb.getEventMsg(activityId, eventData);
            msg.setEvent(eventMsg);
        }
        msg.setPatrons(CrossStrongholdPb.getWildUserMsg(userData));
        return msg;
    }

    private Collection<String> findSameUnionMemberName(StrongholdWildUserData userData) {
        List<String> list = new ArrayList<>();
        for (StrongholdWildUserData data : new ArrayList<>(wildUserDataList)) {
            if (data.getUserBaseInfo().getUnionUid().equals(userData.getUserBaseInfo().getUnionUid())) {
                if (data.getPatrons().getCurrentBlood().compareTo(BigInteger.ZERO) > 0) {
                    list.add(data.getUserBaseInfo().getNickName());
                }
            }
        }
        return list;
    }

    /**
     * 获取据点玩家人数
     *
     * @return
     */
    private int getWildUserNum() {
        int num = 0;
        for (StrongholdWildUserData userData : new ArrayList<>(wildUserDataList)) {
            if (userData.getPatrons().getCurrentBlood().compareTo(BigInteger.ZERO) > 0) {
                num++;
            }
        }
        return num;
    }

    /**
     * 获取同个联盟玩家人数
     *
     * @param userData
     * @return
     */
    private int findSameUnionNum(StrongholdWildUserData userData) {
        int num = 0;
        for (StrongholdWildUserData data : new ArrayList<>(wildUserDataList)) {
            if (data.getUserBaseInfo().getUnionUid().equals(userData.getUserBaseInfo().getUnionUid())) {
                if (data.getPatrons().getCurrentBlood().compareTo(BigInteger.ZERO) > 0) {
                    num++;
                }
            }
        }
        return num;
    }

    /**
     * 获取剩余宝箱数量
     *
     * @return
     */
    private int getLastBoxNum() {
        int num = 0;
        for (StrongholdWildBox box : activityModel.getBoxByWildId(wildId)) {
            if (box.getUserId() == 0) {
                num++;
            }
        }
        return num;
    }

    /**
     * 获取剩余宝箱集合
     *
     * @return
     */
    private List<StrongholdWildBox> getLastBox() {
        List<StrongholdWildBox> list = new ArrayList<>();
        for (StrongholdWildBox box : activityModel.getBoxByWildId(wildId)) {
            if (box.getUserId() == 0) {
                list.add(box);
            }
        }
        return list;
    }

    public StrongholdOpenBoxResult openBox(StrongholdWildUserData wildUserData, int boxId) {
        synchronized (WILD_LOCK) {
            StrongholdWildBox box = activityModel.getBox(boxId);
            if (box == null || box.getUserId() != wildUserData.getUserId()) {
                return new StrongholdOpenBoxResult(GameErrorCode.E_STRONGHOLD_NOT_YOUR_BOX);
            }
            if (!CrossStrongholdActivityMgr.canOpenBox(activityId, box.getType(), box.getPickUpTime())) {
                return new StrongholdOpenBoxResult(GameErrorCode.E_STRONGHOLD_BOX_IN_CD);
            }
            if (box.getOpenTime() != 0) {
                return new StrongholdOpenBoxResult(GameErrorCode.E_STRONGHOLD_NOT_YOUR_BOX);
            }
            wildUserData.removeBox(boxId);
            box.setOpenTime(System.currentTimeMillis());
            String reward = box.getReward();
            int type = box.getType();
            int itemId = CrossStrongholdActivityMgr.getBoxItemId(activityId, type);
            OpenGoodsBagResult randomGoods = TempGoodsBagMgr.getRandomGoods(itemId);
            Property property = randomGoods.getReward();
            property.addProperty(PropertyHelper.parseStringToProperty(reward));
            CrossAutoLogMgr.add(new LogStrongholdBox(
                    activityId,
                    box.getUserId(),
                    0,
                    box.getType(),
                    box.getBoxId(),
                    0,
                    2,
                    CrossStrongholdActivityMgr.getWildName(activityId, wildId)
            ));
            return new StrongholdOpenBoxResult(PropertyHelper.parsePropertyToString(property), activityModel.getBoxList(wildUserData.getBoxList()));
        }
    }
}
